#include <ESP8266WiFi.h>
#include <aJSON.h>

//=============  此处必须修该============
String DEVICEID = "18539"; // 你的设备编号   ==
String  APIKEY = "966f4e716"; // 设备密码==
//=======================================
unsigned long lastCheckInTime = 0; //记录上次报到时间
const unsigned long postingInterval = 40000; // 每隔40秒向服务器报到一次
unsigned long timerTime = 0; //定时器

const char* host = "www.bigiot.net";
const int httpPort = 8181;

int pins = 0;
unsigned char num = 0;
void smartConfig()
{
  WiFi.mode(WIFI_STA);
  Serial.println("Waitting SmartConfig!");
  WiFi.beginSmartConfig();          //开启SmartConfig服务
  while (1)
  {
    delay(500);
    if (WiFi.smartConfigDone())       //连接成功标志
    {
      Serial.println("SmartConfig Success!");

      delay(500);
      Serial.println();
      Serial.printf("SSID:%s\t\n", WiFi.SSID().c_str());      //显示WIFi名
      Serial.printf("PASSWORD:%s\t\n", WiFi.psk().c_str());   //显示WIFi密码
     
      //wifi通后 闪一下
      digitalWrite(pins, LOW);//开
      delay(500);
      digitalWrite(pins, HIGH);//先关闭
      
      Serial.printf("IP address: ");
      Serial.println(WiFi.localIP());
      break;
    }
    else {
      delay(500);
      Serial.print(".");
      num++;
      if (num >= 10)
      {
        Serial.print("\n");
        num = 0;
      }
    }
  }
}


WiFiClient client;

void setup() {

  Serial.begin(115200);

    pinMode(pins, OUTPUT);
    digitalWrite(pins, HIGH);//先关闭
    Serial.println("wifi SSID: ");
    Serial.println(WiFi.SSID());
    Serial.println("wifi PSK: ");
    Serial.println(WiFi.psk());
    WiFi.begin();

  unsigned long startTime = millis();//等20秒
  while (WiFi.status() != WL_CONNECTED && millis() - startTime < 20000)
  {
    Serial.println('.');
    delay(500);
  }
  
   if(WiFi.status() == WL_CONNECTED)  {
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());

      //wifi通后 闪一下
      digitalWrite(pins, LOW);//开
      delay(500);
      digitalWrite(pins, HIGH);//关闭
    }else{
      //10秒后不闪，说明无wifi，进入配置模式
      Serial.println("WiFi not connected!");
      smartConfig();
    }

}


void loop() {

  if (!client.connected()) {
    if (!client.connect(host, httpPort)) {
      Serial.println("connection failed");
      delay(2000);
      return;
    }else{
      Serial.println("connection successd");
    }
  }

  if (millis() - lastCheckInTime > postingInterval || lastCheckInTime == 0) {
    checkIn();
  }

  // Read all the lines of the reply from server and print them to Serial
  if (client.available()) {
  
    String inputString = client.readStringUntil('\n');
    inputString.trim();
    Serial.println(inputString);
    int len = inputString.length() + 1;
    if (inputString.startsWith("{") && inputString.endsWith("}")) {
      char jsonString[len];
      inputString.toCharArray(jsonString, len);
      aJsonObject *msg = aJson.parse(jsonString);
      processMessage(msg);
      aJson.deleteItem(msg);
    }
  }
}

void processMessage(aJsonObject *msg) {
  aJsonObject* method = aJson.getObjectItem(msg, "M");
  aJsonObject* content = aJson.getObjectItem(msg, "C");
  aJsonObject* seconds = aJson.getObjectItem(msg, "sign");
  aJsonObject* client_id = aJson.getObjectItem(msg, "ID");
  if (!method) {
    return;
  }
  String M = method->valuestring;
  if (M == "checkinok") {
    //登陆成功通后闪2下
      digitalWrite(pins, LOW);//开
      delay(500);
      digitalWrite(pins, HIGH);//关闭
      delay(500);
      digitalWrite(pins, LOW);//开
      delay(500);
      digitalWrite(pins, HIGH);//关闭
  }
  if (M == "say") {
    String C = content->valuestring;
    String F_C_ID = client_id->valuestring;
    
    if (C == "timer") {//定时器 尽量不用，计时器，设备不能接收其它命令，且显示不在线。
      String S = seconds->valuestring;
      timerTime = millis();
      digitalWrite(pins, LOW);//开
      sayToClient(F_C_ID, "timmer "+S+" sec");
      Serial.println("timmer "+S+" sec");
      S = S.toInt()*1000;
      while (millis() - timerTime < S.toInt())
      {
        Serial.write('.');
        delay(1000);
      }
      Serial.println("");
      Serial.println("timmer end!");
      digitalWrite(pins, HIGH);//关闭
      sayToClient(F_C_ID, "timmer end!");
     }else if (C == "play") {
      digitalWrite(pins, LOW);
      sayToClient(F_C_ID, "LED All on!");
     }else if (C == "stop") {
      digitalWrite(pins, HIGH);
      sayToClient(F_C_ID, "LED All off!");
    }
    else {
      int pin = C.toInt();//.toInt()
      pinMode(pin, OUTPUT);
      digitalWrite(pin, LOW);
      sayToClient(F_C_ID, "LED pin:" + C+" is LOW");
      delay(3000);
      digitalWrite(pin, HIGH);
      sayToClient(F_C_ID, "LED pin:" + C+" is HIGH");
    }
  }
}

void checkIn() {
  Serial.println("checkIn");
  String msg = "{\"M\":\"checkin\",\"ID\":\"" + DEVICEID + "\",\"K\":\"" + APIKEY + "\"}\n";
  client.print(msg);
  lastCheckInTime = millis();
}

void sayToClient(String client_id, String content) {
  Serial.println("sayToClient");
  String msg = "{\"M\":\"say\",\"ID\":\"" + client_id + "\",\"C\":\"" + content + "\"}\n";
  client.print(msg);
  lastCheckInTime = millis();
}
